package lex.dm.ui.dt;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.*;

import org.lex.swing.Swings;
import org.lex.utils.Pair;

import lex.dm.DTree;
import lex.dm.id3.DataSetUtils;
import lex.dm.id3.ID3Node;
import lex.dm.id3.IDataSet;

public class DecisionTreeDialog extends JDialog
{
	static final boolean DEBUG = false;
	private JPanel gluePane2;
	private JPanel pane = null;
	private JLabel chooseTrainingSetLabel = null;
	private JButton selectTrainingSetButton = null;
	private JLabel generateDTLabel = null;
	private JButton genDTButton = null;
	private JLabel applyTestSetLabel = null;
	private JButton applyDTButton = null;
	private JPanel gluePane = null;
	private JPanel buttonsPane = null;
	private JButton closeButton = null;
	private JCheckBox clusteringCheckBox = null;
	private JButton clusteringButton = null;
	// --------------------------------------
	private final DTree app;
	private String sql = null;
	private IDataSet trainingSet = null;
	private IDataSet testingSet = null;
	private ID3Node rootNode = null;

	public static void main( String[] args )
	{
		Swings.show( new DecisionTreeDialog( null ) );
	}

	/**
	 * @param owner
	 */
	public DecisionTreeDialog( Window owner )
	{
		super( owner );
		this.app = DTree.getApplication();
		initialize();
		this.setLocationRelativeTo( owner );
	}

	private void selectTrainingSet()
	{
		this.sql = DataSetSelector.getSQL( app.getRootWindow() );
		this.setDataSet( DTUtils.loadDataSet( app.getRootWindow(), sql ) );
		if( DEBUG )
		{
			System.out.println( "Load training set:" );
			DataSetUtils.dump( trainingSet, System.out );
			System.out.println();
		}
	}

	private void clustering()
	{
		this.setDataSet( ClusteringDialog.cluster( app.getRootWindow(), trainingSet, testingSet ) );
		if( DEBUG )
		{
			System.out.println( "After clustering:" );
			DataSetUtils.dump( trainingSet, System.out );
			System.out.println();
		}
	}

	private void generateDT()
	{
		this.rootNode = DTUtils.generateDT( app.getRootWindow(), trainingSet );
	}

	private void applyDT()
	{
		// DTUtils.applyClassification( app.getRootWindow(), rootNode,
		// trainingSet );
		DTUtils.applyClassification( app.getRootWindow(), rootNode, testingSet );
	}

	private void setDataSet( Pair<? extends IDataSet, ? extends IDataSet> p )
	{
		if( null != p )
		{
			this.trainingSet = p.first();
			this.testingSet = p.second();
		}
	}

	/***************************************************************************
	 * Construct UI
	 **************************************************************************/
	private void hookActionHandlers()
	{
		this.getSelectTrainingSetButton().addActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				selectTrainingSet();
			}
		} );
		this.getGenDTButton().addActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				generateDT();
			}
		} );
		this.getClusteringCheckBox().addActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				getClusteringButton().setEnabled( clusteringCheckBox.isSelected() );
			}
		} );
		this.clusteringButton.setEnabled( this.clusteringCheckBox.isSelected() );
		this.getApplyDTButton().addActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				applyDT();
			}
		} );
		this.getCloseButton().addActionListener( new ActionListener(){
			@Override
			public void actionPerformed( ActionEvent e )
			{
				dispose();
			}
		} );
	}

	private void initialize()
	{
		this.setSize( 350, 240 );
		this.setDefaultCloseOperation( JDialog.DISPOSE_ON_CLOSE );
		this.setContentPane( getPane() );
		this.setTitle( "Create Decision Tree" );
		this.hookActionHandlers();
	}

	/**
	 * This method initializes pane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getPane()
	{
		if( pane == null )
		{
			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
			gridBagConstraints9.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints9.gridx = 1;
			gridBagConstraints9.anchor = GridBagConstraints.WEST;
			gridBagConstraints9.insets = new Insets( 0, 0, 6, 0 );
			gridBagConstraints9.gridy = 1;
			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
			gridBagConstraints8.gridx = 0;
			gridBagConstraints8.anchor = GridBagConstraints.WEST;
			gridBagConstraints8.insets = new Insets( 0, 0, 6, 6 );
			gridBagConstraints8.gridy = 1;
			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
			gridBagConstraints7.gridx = 0;
			gridBagConstraints7.gridwidth = 3;
			gridBagConstraints7.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints7.weightx = 10.0;
			gridBagConstraints7.gridy = 5;
			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
			gridBagConstraints6.gridx = 0;
			gridBagConstraints6.gridwidth = 3;
			gridBagConstraints6.weightx = 10.0;
			gridBagConstraints6.weighty = 10.0;
			gridBagConstraints6.fill = GridBagConstraints.BOTH;
			gridBagConstraints6.gridy = 4;
			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
			gridBagConstraints5.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints5.gridx = 1;
			gridBagConstraints5.anchor = GridBagConstraints.WEST;
			gridBagConstraints5.insets = new Insets( 0, 0, 12, 0 );
			gridBagConstraints5.gridy = 3;
			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
			gridBagConstraints4.gridx = 0;
			gridBagConstraints4.anchor = GridBagConstraints.WEST;
			gridBagConstraints4.insets = new Insets( 0, 0, 12, 6 );
			gridBagConstraints4.gridy = 3;
			applyTestSetLabel = new JLabel();
			applyTestSetLabel.setText( "4. Run Classification" );
			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
			gridBagConstraints3.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints3.gridx = 1;
			gridBagConstraints3.anchor = GridBagConstraints.WEST;
			gridBagConstraints3.insets = new Insets( 0, 0, 6, 0 );
			gridBagConstraints3.gridy = 2;
			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
			gridBagConstraints2.gridx = 0;
			gridBagConstraints2.anchor = GridBagConstraints.WEST;
			gridBagConstraints2.insets = new Insets( 0, 0, 6, 6 );
			gridBagConstraints2.gridy = 2;
			generateDTLabel = new JLabel();
			generateDTLabel.setText( "3. Generate Decision Tree:" );
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints1.gridx = 1;
			gridBagConstraints1.anchor = GridBagConstraints.WEST;
			gridBagConstraints1.insets = new Insets( 0, 0, 6, 0 );
			gridBagConstraints1.gridy = 0;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.gridx = 0;
			gridBagConstraints.anchor = GridBagConstraints.WEST;
			gridBagConstraints.insets = new Insets( 0, 0, 6, 6 );
			gridBagConstraints.gridy = 0;
			chooseTrainingSetLabel = new JLabel();
			chooseTrainingSetLabel.setText( "1. Select Training Set:" );
			pane = new JPanel();
			final GridBagLayout gridBagLayout = new GridBagLayout();
			pane.setLayout( gridBagLayout );
			pane.setBorder( BorderFactory.createEmptyBorder( 12, 12, 12, 12 ) );
			pane.add( chooseTrainingSetLabel, gridBagConstraints );
			pane.add( getSelectTrainingSetButton(), gridBagConstraints1 );
			pane.add( generateDTLabel, gridBagConstraints2 );
			pane.add( getGenDTButton(), gridBagConstraints3 );
			pane.add( applyTestSetLabel, gridBagConstraints4 );
			pane.add( getApplyDTButton(), gridBagConstraints5 );
			pane.add( getGluePane(), gridBagConstraints6 );
			pane.add( getButtonsPane(), gridBagConstraints7 );
			final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints();
			gridBagConstraints_1.weighty = 0.0;
			gridBagConstraints_1.weightx = 10;
			gridBagConstraints_1.fill = GridBagConstraints.HORIZONTAL;
			gridBagConstraints_1.gridheight = 4;
			gridBagConstraints_1.gridy = 0;
			gridBagConstraints_1.gridx = 2;
			pane.add( getGluePane2(), gridBagConstraints_1 );
			pane.add( getClusteringCheckBox(), gridBagConstraints8 );
			pane.add( getClusteringButton(), gridBagConstraints9 );
		}
		return pane;
	}

	/**
	 * This method initializes selectTrainingSetButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getSelectTrainingSetButton()
	{
		if( selectTrainingSetButton == null )
		{
			selectTrainingSetButton = new JButton();
			selectTrainingSetButton.setText( "Training Set..." );
		}
		return selectTrainingSetButton;
	}

	/**
	 * This method initializes genDTButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getGenDTButton()
	{
		if( genDTButton == null )
		{
			genDTButton = new JButton();
			genDTButton.setMnemonic( KeyEvent.VK_UNDEFINED );
			genDTButton.setText( "Generate..." );
		}
		return genDTButton;
	}

	/**
	 * This method initializes applyDTButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getApplyDTButton()
	{
		if( applyDTButton == null )
		{
			applyDTButton = new JButton();
			applyDTButton.setText( "Classify..." );
		}
		return applyDTButton;
	}

	/**
	 * This method initializes gluePane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getGluePane()
	{
		if( gluePane == null )
		{
			gluePane = new JPanel();
			gluePane.setLayout( new GridBagLayout() );
		}
		return gluePane;
	}

	/**
	 * This method initializes buttonsPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getButtonsPane()
	{
		if( buttonsPane == null )
		{
			FlowLayout flowLayout = new FlowLayout();
			flowLayout.setHgap( 0 );
			flowLayout.setVgap( 0 );
			buttonsPane = new JPanel();
			buttonsPane.setLayout( flowLayout );
			buttonsPane.add( getCloseButton(), null );
		}
		return buttonsPane;
	}

	/**
	 * This method initializes closeButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getCloseButton()
	{
		if( closeButton == null )
		{
			closeButton = new JButton();
			closeButton.setText( "Close" );
		}
		return closeButton;
	}

	/**
	 * This method initializes clusteringCheckBox
	 * 
	 * @return javax.swing.JCheckBox
	 */
	private JCheckBox getClusteringCheckBox()
	{
		if( clusteringCheckBox == null )
		{
			clusteringCheckBox = new JCheckBox();
			clusteringCheckBox.setText( "2. ��ɢ����������" );
		}
		return clusteringCheckBox;
	}

	/**
	 * This method initializes clusteringButton
	 * 
	 * @return javax.swing.JButton
	 */
	private JButton getClusteringButton()
	{
		if( clusteringButton == null )
		{
			clusteringButton = new JButton();
			clusteringButton.setText( "��ɢ��..." );
			clusteringButton.addActionListener( new ActionListener(){
				@Override
				public void actionPerformed( ActionEvent e )
				{
					clustering();
				}
			} );
		}
		return clusteringButton;
	}

	/**
	 * @return
	 */
	private JPanel getGluePane2()
	{
		if( gluePane2 == null )
		{
			gluePane2 = new JPanel();
		}
		return gluePane2;
	}
} // @jve:decl-index=0:visual-constraint="10,10"
